/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.nextsql.renderizar;

import br.com.nextsql.*;
import java.awt.*;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.text.*;

/**
 *
 * @author rho
 */
public class AcharPalavras extends DefaultStyledDocument {
    private Properties principal;
    private Properties comandosBasicos = new Properties();
    public AcharPalavras(Properties comandos){
        this.comandosBasicos = comandos;
        principal = GlobalConf.lerPropriedades();
        try {
            this.definicaoEstilos();
        } catch (BadLocationException ex) {
            Logger.getLogger(AcharPalavras.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    @Override
    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
        super.insertString(offs, str, a);
        this.definicaoEstilos();
    }
    @Override
    public void remove(int offs, int len) throws BadLocationException{
        super.remove(offs, len);
        this.definicaoEstilos();
    }
    private void definicaoEstilos() throws BadLocationException{
        StyleContext sc = new StyleContext();
        int searchMeLength = (getLength() + 1);
        String searchMe = super.getText(0, searchMeLength).toUpperCase();
        //Padrão
        final Style formatacaoPadrao = sc.addStyle("Teste", null);
        StyleConstants.setBackground(formatacaoPadrao, Color.WHITE);
        StyleConstants.setBold(formatacaoPadrao, true);
        StyleConstants.setFontFamily(formatacaoPadrao, principal.getProperty("fonte"));
        StyleConstants.setFontSize(formatacaoPadrao, Integer.parseInt(principal.getProperty("fonte.tamanho")));
        StyleConstants.setForeground(formatacaoPadrao, Color.BLACK);
        StyleConstants.setItalic(formatacaoPadrao, false);
        StyleConstants.setUnderline(formatacaoPadrao, false);
        super.setCharacterAttributes(0, searchMeLength, formatacaoPadrao, true);
        //Fim Padrão 
        //Palavras reservadas
        final Style estiloPalavrasReservadas = sc.addStyle("Palavras Reservadas", null);
        StyleConstants.setForeground(estiloPalavrasReservadas, Color.BLUE);
        StyleConstants.setFontSize(estiloPalavrasReservadas, Integer.parseInt(principal.getProperty("fonte.tamanho")));
        StyleConstants.setFontFamily(estiloPalavrasReservadas, principal.getProperty("fonte"));
        StyleConstants.setBold(estiloPalavrasReservadas, true);
        //Funções
        final Style estiloFuncoes = sc.addStyle("Funções", null);
        StyleConstants.setForeground(estiloFuncoes, Color.GREEN);
        StyleConstants.setFontSize(estiloFuncoes, Integer.parseInt(principal.getProperty("fonte.tamanho")));
        StyleConstants.setFontFamily(estiloFuncoes, principal.getProperty("fonte"));
        StyleConstants.setBold(estiloFuncoes, true);
        //Estilo Simbolos
        final Style estiloSimbolos = sc.addStyle("Simbolos", null);
        StyleConstants.setForeground(estiloSimbolos, Color.GRAY);
        StyleConstants.setFontSize(estiloSimbolos, Integer.parseInt(principal.getProperty("fonte.tamanho")));
        StyleConstants.setFontFamily(estiloSimbolos, principal.getProperty("fonte"));
        StyleConstants.setBold(estiloSimbolos, true);
        //Estilo Simbolos
        final Style estiloAspas = sc.addStyle("aspas", null);
        StyleConstants.setForeground(estiloAspas, Color.MAGENTA);
        StyleConstants.setFontSize(estiloAspas, Integer.parseInt(principal.getProperty("fonte.tamanho")));
        StyleConstants.setFontFamily(estiloAspas, principal.getProperty("fonte"));
        StyleConstants.setBold(estiloAspas, true);
        final Style estiloComentarios = sc.addStyle("aspas", null);
        StyleConstants.setForeground(estiloComentarios, Color.MAGENTA);
        StyleConstants.setFontSize(estiloComentarios, Integer.parseInt(principal.getProperty("fonte.tamanho")));
        StyleConstants.setFontFamily(estiloComentarios, principal.getProperty("fonte"));
        StyleConstants.setBold(estiloComentarios, true);
        String[] aspas = (comandosBasicos.getProperty("ERAspas").split("\\ ;SEPARADOR; "));
        String[] comentarios = (comandosBasicos.getProperty("ERComentarios").split("\\ ;SEPARADOR; "));
        String[] funcoes = (comandosBasicos.getProperty("Funcoes").split("\\,"));
        String[] ignorar = (comandosBasicos.getProperty("Ignorar").split("\\ ;SEPARADOR; "));
        String[] palavras = (comandosBasicos.getProperty("PalavrasReservadas").split("\\,"));
        String[] separadoresint = (comandosBasicos.getProperty("PalavrasReservadasSeparador").split("\\,"));
        String[] simbolos = (comandosBasicos.getProperty("Simbolos").split("\\ "));
        int separadores[] = new int[separadoresint.length+simbolos.length];
        int val = 0;
        for (int i = 0; i < ignorar.length; i++){
            searchMe = searchMe.replaceAll(ignorar[i], "/§");
        }
        for(;val<separadoresint.length;val++){
            separadores[val] = Integer.parseInt(separadoresint[val]);
        }
        for(;val<separadoresint.length+simbolos.length;val++){
            separadores[val] = (int)simbolos[val-separadoresint.length].charAt(0);
        }
        //Palavras reservadas
        for (int i = 0; i < palavras.length; i++){
            String findMe = palavras[i];
            int findMeLength = findMe.length();
            for (int y = 0; y <= (searchMeLength - (findMeLength+1)); y++){
                boolean permitir = false;
                String t = super.getText(y, 1);
                int ct = (int)t.charAt(0);
                permitir = false;
                for(int a=0; a<separadores.length && !permitir; a++){
                    if(separadores[a] == ct){
                        permitir = true;
                    }
                }
                int yt =(y==0)?((permitir)? 1:y):y+1;
                if(y==0){
                    permitir = true;
                }
                if (permitir && searchMe.regionMatches(yt, findMe, 0, findMeLength)){
                    int fim = (yt+findMeLength >= searchMeLength)? searchMeLength:yt+findMeLength;
                    t = searchMe.substring(fim, fim+1);
                    ct = (int)t.charAt(0);
                    permitir = false;
                    for(int a=0; a<separadores.length && !permitir; a++){
                        if(separadores[a]==ct){
                            super.setCharacterAttributes(yt, findMeLength, estiloPalavrasReservadas, true);
                            permitir = true;
                        }
                    }
                }
            }
        }
        //Funções
        for (int i = 0; i < funcoes.length; i++){
            String findMe = funcoes[i];
            int findMeLength = findMe.length();
            for (int y = 0; y <= (searchMeLength - (findMeLength+1)); y++){
                boolean permitir = false;
                String t = super.getText(y, 1);
                int ct = (int)t.charAt(0);
                permitir = false;
                for(int a=0; a<separadores.length && !permitir; a++){
                    if(separadores[a]==ct){
                        permitir = true;
                    }
                }
                int yt =(y==0)?((permitir)? 1:y):y+1;
                if(y==0){
                    permitir = true;
                }
                if (permitir && searchMe.regionMatches(yt, findMe, 0, findMeLength)){
                    int fim = (yt+findMeLength >= searchMeLength)? searchMeLength:yt+findMeLength;
                    t = searchMe.substring(fim, fim+1);
                    ct = (int)t.charAt(0);
                    permitir = false;
                    for(int a=0; a<separadores.length && !permitir; a++){
                        if(separadores[a]==ct){
                            super.setCharacterAttributes(yt, findMeLength, estiloFuncoes, true);
                            permitir = true;
                        }
                    }
                }
            }
        }
        //Simbolos
        for (int i = 0; i < simbolos.length; i++){
            String findMe = simbolos[i];
            int findMeLength = findMe.length();
            for (int y = 0; y <= (searchMeLength - (findMeLength+1)); y++){
                if (searchMe.regionMatches(y, findMe, 0, findMeLength)){
                    super.setCharacterAttributes(y, findMeLength, estiloSimbolos, true);
                }
            }
        }
        //Aspas
        // Aspas " ou ' ou `
        for(int i=0; i < aspas.length; i++){
            Pattern er = Pattern.compile(aspas[i]);
            Matcher m = er.matcher(searchMe);
            while(m.find()){
                int mIni = m.start();
                int mFim = m.end()-m.start();
                super.setCharacterAttributes(mIni, mFim, estiloAspas, true);
            }
        }
        // comentário /* */ ou --
        for(int i=0; i<comentarios.length; i++){
            Pattern er = Pattern.compile(comentarios[i]);
            Matcher m = er.matcher(searchMe);
            while(m.find()){
                super.setCharacterAttributes(m.start(), m.end()-m.start(), estiloComentarios, true);
            }
        }
    }
}
